Skip to content

playground: Add ability to fix imports via goimports. #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 20, 2015
Merged

Conversation

dmitshur
Copy link
Member

Resolves #29.

This is a WIP, there are still a few things I want to clean up and do. Edit: All done.

  • Include gopherjs.com/gopherjs/gopherjs/js package in the pre-baked list.
  • Revisit and ensure imports functionality is up to date and cannot be used from upstream.
    • When I originally wrote this code a while ago, I found that it was necessary to copy and modify imports package code to avoid reading from disk, because some private internal configuration had to be changed to make that work. Just want to confirm that's still the case.
    • Done in 0b05872. I've confirmed it's necessary to make a copy of upstream package in order to disable/remove the code that uses disk IO to initialize pkgIndex and causes syscall errors in browser environment.
  • Move imports package under internal subfolder. We probably don't want others to be importing it.
  • Build the playground JS code.

However, it's functional and ready for initial review.

@dmitshur
Copy link
Member Author

Ok, everything is done from my side and this is ready to merge. It can be squashed into fewer commits after review.

PTAL.

@dmitshur dmitshur changed the title WIP: playground: Add ability to fix imports via goimports. playground: Add ability to fix imports via goimports. Sep 13, 2015
@neelance
Copy link
Member

What are the changes to the imports package? Is there a chance to get them upstream?

@dmitshur
Copy link
Member Author

What are the changes to the imports package?

From the PR description (with emphasis added):

  • Revisit and ensure imports functionality is up to date and cannot be used from upstream.
    • When I originally wrote this code a while ago, I found that it was necessary to copy and modify imports package code to avoid reading from disk, because some private internal configuration had to be changed to make that work. Just want to confirm that's still the case.
    • Done in 0b05872. I've confirmed it's necessary to make a copy of upstream package in order to disable/remove the code that uses disk IO to initialize pkgIndex and causes syscall errors in browser environment.

You can visualize the diff with any tool by comparing the folders of this imports package against golang.org/x/tools/imports. It looks something like this:

image

image

image

In summary, it removes some unused code (reducing the functionality to use in-memory pre-computed database of packages only, no falling back to reading from disk), and sets some internal configuration variables. Since those variables not exported, the upstream package cannot be directly used.

One alternative I see is not removing the unused code, but copying the upstream imports package as is, but adding a new config.go file that has:

func init() {
    // Override some internal funcs.
    importPathToName = importPathToNameBasic
    findImport = findImportStdlib
}

Which would make the forked package a little easier to maintain, but it will have a lot of extra unused code and potentially still cause syscall errors.

Is there a chance to get them upstream?

The problem is that the imports package does not use build tags to detect if it's running in an environment where doing direct disk IO is not a possibility.

One idea for how to resolve that upstream is to make a CL that makes the package friendly to such IO-less environments is to make use of the nacl build tag. I doubt the Go team will accept moving disk IO into a // +build !js file, but they may accept a // +build !nacl one.

However, even if that happens, I've built a custom index including Go 1.5 standard library and github.com/gopherjs/gopherjs/js package. This on its own means the upstream package cannot be used directly.

Concluding note

I realize this is a lot of code and it seems hard to maintain. However, I've considered that, and I think it will not cause a lot of problems for these reasons:

  • Updating it is as simple as go generate github.com/gopherjs/gopherjs.github.io/playground/internal/imports.
  • The imports package is mature and stable. It hasn't changed much in the last 2 years, it's unlikely to change much in the next 3.
  • I will very likely maintain it for the next 3+ years at least.

…packages.

Generate zstdlib.go, include Go 1.5, skip syscall.

Use a modified version of cmd/api tool to include gopherjs/js package.

Add go generate step for imports package to update.sh.
Add ability to turn off goimports. As suggested by @dominikh.
@dmitshur
Copy link
Member Author

I've squashed and rebased this PR into 4 logical commits, that should be easier to review, maintain and understand in the future.

This has LGTM and is ready to merge from my side.

go func() {
var out []byte
var err error
switch dom.GetWindow().Document().GetElementByID("imports").(*dom.HTMLInputElement).Checked {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There may be a better angular way of accessing the value of a checkbox; I do not know what it is, so I just accessed the DOM directly.

@dmitshur
Copy link
Member Author

@neelance, will you have a chance to review this soon? It's ready to merge from my side.

@neelance
Copy link
Member

I think it is reasonable to ask for golang.org/x/tools/imports to support something like http://golang.org/pkg/go/build/#Context, which provides all functions for file system access. We should at least ask for it to show that there is a need. In the meantime vendoring should be okay.

Factor out []byte(scope.Get("code").String()) into a local variable.

Rebuild playground.
@dmitshur
Copy link
Member Author

I think it is reasonable to ask for golang.org/x/tools/imports to support something like http://golang.org/pkg/go/build/#Context, which provides all functions for file system access. We should at least ask for it to show that there is a need. In the meantime vendoring should be okay.

I will try, but a few things:

  • build.Context isn't completely applicable here. It's a great abstraction for accessing known packages in a customizable way. But imports package works at a filesystem-access level before it can work at package level. It needs to walk the GOPATH and find all available packages, and build an index. It's not possible to walk the GOPATH and find a list of all existing Go packages via build.Context abstraction.

  • Unless you meant something like build.Context but for imports package. Similar to Context of gotool package: https://godoc.org/github.com/kisielk/gotool#Context.

  • So what's really needed is just a way to configure the internal options of imports package. Something like:

    // Or "Context" or "Configuration" or whatever name works best.
    type Config struct {
        ImportPathToName func(importPath string) (packageName string)
        LoadExports      func(dir string) map[string]bool
        FindImport       func(pkgName string, symbols map[string]bool) (string, bool, error)
    }
    
    func (c *Config) Process(filename string, src []byte, opt *Options) ([]byte, error) { ... }
    
    func Process(filename string, src []byte, opt *Options) ([]byte, error) {
        return defaultConfig.Process(filename, src, opt)
    }
  • Ideally, things that rely on raw filesystem access and import packages like os can be hidden behind a build tag for systems that don't have filesystems (perhaps nacl build tag). Otherwise GopherJS will produce warnings for syscall package being imported in browser (unless it gets eliminated via DCE since it won't be used and that's enough to prevent the warning from happening, not sure if DCE would do that).

I'll file an issue with the feature request.

@dmitshur
Copy link
Member Author

Filed issue golang/go#12696.

With that, I've addressed all your outstanding comments. PTAL.

@neelance
Copy link
Member

LGTM :)

dmitshur added a commit that referenced this pull request Sep 20, 2015
playground: Add ability to fix imports via goimports.
@dmitshur dmitshur merged commit 7f5af7c into master Sep 20, 2015
@dmitshur dmitshur deleted the goimports branch September 20, 2015 00:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants